﻿using System.Linq.Expressions;

/// <summary>
/// 表达式参数
/// </summary>
public class ParameterRebinder : ExpressionVisitor
{
    /// <summary>
    /// 参数字典
    /// </summary>
    private readonly Dictionary<ParameterExpression, ParameterExpression> map;

    public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
    {
        this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
    }

    /// <summary>
    /// 参数替换
    /// </summary>
    /// <param name="map"></param>
    /// <param name="exp"></param>
    /// <returns></returns>
    public static Expression ReplaceParameters(
        Dictionary<ParameterExpression, ParameterExpression> map,
        Expression exp
    )
    {
        return new ParameterRebinder(map).Visit(exp);
    }

    /// <summary>
    /// 表达式转换
    /// </summary>
    /// <param name="p"></param>
    /// <returns></returns>
    protected override Expression VisitParameter(ParameterExpression p)
    {
        if (map.TryGetValue(p, out ParameterExpression replacement))
        {
            p = replacement;
        }
        return base.VisitParameter(p);
    }
}
